package net.yxsoft.service.infrastructure;

import com.jfinal.aop.Before;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;
import net.yxsoft.bean.JsTreeNode;
import net.yxsoft.bean.JsTreeNodeFieldKey;
import net.yxsoft.enumclass.StateEnumCls;
import net.yxsoft.enumclass.WhetherEnumCls;
import net.yxsoft.kit.Helper;
import net.yxsoft.kit.JsTreeNodeKit;
import net.yxsoft.resource.Res;
import net.yxsoft.model.infrastructure.TsGroup;
import net.yxsoft.model.infrastructure.TsUgRelation;
import net.yxsoft.service.common.BaseService;
import rapid.core.Authuser;

import java.lang.reflect.InvocationTargetException;
import java.sql.Date;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Leo on 2016/5/13.
 */
public class GroupService extends BaseService {

  public static final GroupService INSTANCE = new GroupService();

  public List<TsGroup> findAll() {
    return TsGroup.dao.find("select * from ts_group order by id");
  }

  /**
  * @MethodName: getGroupById
  * @Description: 根据组主键获取组信息
  * @param: groupId 组主键
  * @return * @return net.yxsoft.model.infrastructure.TsGroup
  * @throws
  * @date 2023/8/31 13:12
  * @author wj
  */
  public TsGroup getGroupById(String groupId) throws IllegalAccessException {
    TsGroup tsGroup = TsGroup.dao.findById(groupId);

    TsGroup tsGroupParent = TsGroup.dao.findById(tsGroup.getPid());
    if(tsGroupParent != null) {
      tsGroup.put("PNAME", tsGroupParent.getName());
      tsGroup.put("PCODE", tsGroupParent.getCode());
    } else {
      tsGroup.put("PNAME", "此项为顶级");
      tsGroup.put("PCODE", "此项为顶级");
    }
    tsGroup.put("ENABLED_CH", StateEnumCls.getObject(StateEnumCls.class, tsGroup.getEnabled()).getText());
    tsGroup.put("LOCKED_CH", WhetherEnumCls.getObject(WhetherEnumCls.class, tsGroup.getLocked()).getText());

    return tsGroup;
  }

  /**
  * @MethodName: saveGroup
  * @Description: 保存组信息
  * @param: group 实体
   * @param: user 实体
  * @return * @return int
  * @throws
  * @date 2023/8/31 13:12
  * @author wj
  */
  public int saveGroup(TsGroup group, Authuser user) {
    boolean result = false;
    String operation = "";
    if(StrKit.notNull(user)) {
      Date date = new Date(System.currentTimeMillis());
      String userId = user.getId();
      String userNam = user.getName();

      group.setEditorId(userId);
      group.setEditorName(userNam);
      group.setUpdateTime(date);

      if(group.getId() == null) {
        if(TsGroup.dao.find("SELECT 1 FROM TS_GROUP WHERE CODE = ? ", group.getCode()).size() > 0) {
          return -1; //code重复
        }
        if(TsGroup.dao.find("SELECT 1 FROM TS_GROUP WHERE  NAME = ?",  group.getName()).size() > 0) {
          return -2; //code重复
        }
        group.setId(Helper.bulidUUID());
        if(group.getPid() == null) {
          group.setPid(Res.GROUP_ROOT_FIRST_CODE); //第一级默认父ID为0
        }
        group.setCreatorId(userId);
        group.setCreatorName(userNam);
        group.setCreateTime(date);

        result = group.save();
        operation = "新增";
      } else {
        if(TsGroup.dao.find("SELECT 1 FROM TS_GROUP WHERE CODE = ?  AND ID <> ?", group.getCode(), group.getId()).size() > 0) {
          return -1; //code重复
        }
        if(TsGroup.dao.find("SELECT 1 FROM TS_GROUP WHERE  NAME = ? AND ID <> ?", group.getName(), group.getId()).size() > 0) {
          return -2; //code重复
        }

        TsGroup tsGroup = TsGroup.dao.findById(group.getId());
        tsGroup.set("NAME", group.getName());
        tsGroup.set("CODE", group.getCode());
        tsGroup.set("ENABLED", group.getEnabled());
        tsGroup.set("LOCKED", group.getLocked());
        tsGroup.set("NOTE", group.getNote());

        result = tsGroup.update();
        operation = "修改";
      }
    }

    if(result) {
      log(user.getId(), user.getName(), "系统管理/机构管理", operation, user.getIp(), "主键：" + group.getId() + "，名称：" + group.getName() + "，编号：" + group.getCode());
      return 1;
    } else {
      return 0;
    }
  }

  /**
  * @MethodName: deleteGroupById
  * @Description: 根据主键删除组
  * @param: groupId 主键
   * @param: user
  * @return * @return boolean
  * @throws
  * @date 2023/8/31 13:12
  * @author wj
  */
  @Before(Tx.class)
  public boolean deleteGroupById(String groupId, Authuser user) throws SQLException {
    boolean result = false;
    if(StrKit.notBlank(groupId)) {
      if(groupId.equals(Res.GROUP_ROOT_CODE)) {
        return false;
      }

      try {
        deleteRelatedTerms(groupId, user);
        result = true;
      } catch(SQLException e) {
        throw e;
      }
    }

    return result;
  }

  /**
  * @MethodName: deleteGroups
  * @Description: 根据主键集合删除组
  * @param: groupIds 组主键集合
   * @param: user
  * @return * @return boolean
  * @throws
  * @date 2023/8/31 13:13
  * @author wj
  */
  @Before(Tx.class)
  public boolean deleteGroups(String[] groupIds, Authuser user) throws SQLException {
    boolean result = false;

    if(groupIds.length > 0) {
      try {
        for(String groupId : groupIds) {
          deleteRelatedTerms(groupId, user);
        }
        result = true;
      } catch(SQLException e) {
        throw e;
      }
    }

    return result;
  }

  /**
  * @MethodName: getGroupsTree
  * @Description: 获取组树
  * @param:
  * @return * @return java.util.List<net.yxsoft.bean.JsTreeNode>
  * @throws
  * @date 2023/8/31 13:13
  * @author wj
  */
  public List<JsTreeNode> getGroupsTree() throws NoSuchMethodException, SecurityException, InvocationTargetException, IllegalAccessException {
    JsTreeNodeFieldKey tnfk = new JsTreeNodeFieldKey("Id", "Name", "Pid");
    tnfk.setLeafKey("Pid");
    tnfk.setLeafValue("0");

    List<TsGroup> grouplist = TsGroup.dao.find("SELECT ID, PID, NAME, CODE FROM TS_GROUP ORDER BY CODE, SORT_ID ASC");
    for(TsGroup tsGroup : grouplist) {
      tsGroup.setName(tsGroup.getName() + "[" + tsGroup.getCode() + "]");
    }

    return JsTreeNodeKit.SerializeJsTreeData(tnfk, grouplist);
  }

  /**
  * @MethodName: deleteRelatedTerms
  * @Description: 删除组子项和关联项
  * @param: groupId 组主键
   * @param: user
  * @return * @return void
  * @throws
  * @date 2023/8/31 13:13
  * @author wj
  */
  private void deleteRelatedTerms(String groupId, Authuser user) throws SQLException {
    try {
      List<TsUgRelation> ugs = TsUgRelation.dao.find("SELECT * FROM TS_UG_RELATION WHERE GROUP_ID = ?", groupId);
      if(ugs.size() > 0) {
        for(TsUgRelation tsUgRelation : ugs) {
          tsUgRelation.delete();
        }
      }

      TsGroup.dao.deleteById(groupId);
      log(user.getId(), user.getName(), "系统管理/机构管理", "删除", user.getIp(), "主键：" + groupId);
      List<TsGroup> groups = TsGroup.dao.find("SELECT ID FROM TS_GROUP WHERE PID = ?", groupId);

      if(groups.size() > 0) {
        for(TsGroup tsGroup : groups) {
          deleteRelatedTerms(tsGroup.getId().toString(), user);
        }
      }

    } catch(SQLException e) {
      throw e;
    }
  }
  
  /**
  * @MethodName: getGroupWithStores
  * @Description:  获取门店
  * @param: userid
  * @return * @return java.util.List<net.yxsoft.model.infrastructure.TsGroup>
  * @throws
  * @date 2023/8/31 13:14
  * @author wj
  */
  public List<TsGroup> getGroupWithStores(String userid) {
    List<TsGroup> _returnData = new ArrayList<TsGroup>();
    _returnData = TsGroup.dao.find("SELECT B.* FROM TS_UDP_RELATION A " +
                                     "INNER JOIN TS_GROUP B ON A.GROUP_ID = B.ID " +
                                     "WHERE A.USER_ID =? AND LENGTH(B.CODE) = 3 AND B.PID <> '0' AND B.ENABLED = '1'", userid);
    return _returnData;
  }

  /**
  * @MethodName: getCodeById
  * @Description: 
  * @param: id
  * @return * @return java.lang.String
  * @throws 
  * @date 2023/8/31 13:35
  * @author wj 
  */
  public String getCodeById(int id) {
    Record rd = Db.findFirst("select code from ts_group where id = ?", id);
    if(rd != null) {
      return rd.get("code");
    }

    return "";
  }
}
